﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace dst
{
    class MulExp<T> : Exp where T : Exp
    {
        List<T> subExps = new List<T>();

        private MulExp()
        {
            this.sig = 1;
        }

        private void AddSubExp(params T[] eles)
        {
            for (int i = 0; i < eles.Length; i++)
            {
                this.subExps.Add(eles[i]);
                this.sig *= eles[i].Sign;
                this.sig %= Util.P128;
            }
        }

        public static Exp GetMul(params T[] eles)
        {
            MulExp<T> m = new MulExp<T>();
            m.AddSubExp(eles);
            m.subExps.Sort();
            return (Exp)Util.simpTable.Add(m.Sign, m);
        }


        protected override Exp Add(Exp a)
        {
            if (a is MulExp<Exp>)
                return AddExp<Exp>.GetAdd(this, a);
            else if (a is AddExp<Exp>)
                return a + this;
            else
                throw new NotImplementedException();
        }

        public override int CompareTo(Exp other)
        {
            if (other is MulExp<Exp>)
            {
                int min = this.subExps.Count < ((MulExp<Exp>)other).subExps.Count ? this.subExps.Count : ((MulExp<Exp>)other).subExps.Count;
                for (int i = 0; i < min; i++)
                {
                    int r = this.subExps[i].CompareTo(((MulExp<Exp>)other).subExps[i]);
                    if (r != 0)
                        return r;
                }

                if (this.subExps.Count > min)
                    return 1;
                else if (((MulExp<Exp>)other).subExps.Count > min)
                    return -1;
                else
                    return 0;
            }
            else
                return 0;
        }

        public override Exp Factor(params Ele[] es)
        {
            if (es.Length > 1)
                throw new Exception("no sense");

            if (this.subExps.Count > 1)
            {
                if (this.subExps[0] == es[0])
                    return this.subExps[1];
                else
                    return this.subExps[0];
            }
            else
                throw new Exception("no sense");
        }

        public override bool Contains(Exp e)
        {
            for (int i = 0; i < subExps.Count; i++)
            {
                if (subExps[i] == e)
                    return true;
            }
            return false;
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < subExps.Count; i++)
                sb.Append(subExps[i].ToString() + "*");

            string s = sb.ToString();
            if (s.Length > 0)
                s = s.Substring(0, s.Length - 1);

            return s;
        }
    }
}
